﻿using JiveMessenger.Models;
using JiveMessenger.Utilities;
using JiveMessenger.ViewModels;
using JmShared;
using NLog;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace JiveMessenger.Converters
{
    public class BooleanToUpdaterButtonTextConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool success = (bool)value;
            if (success)
                return "Restart to complete";
            else
                return "Close";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ValidateEmoticonConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            bool validShortcut = (bool)values[0];
            bool emoticonFileExists = (bool)values[1];
            return validShortcut && !emoticonFileExists;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class BoolToInvertedBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is bool)
            {
                bool boolValue = (bool)value;
                return !boolValue;
            }
            else
                return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException("ConvertBack() of BoolToInvertedBoolConverter is not implemented");
        }
    }

    public class DownloadErrorToBackgroundBrushConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int code = (int)value;
            if (code == 0)
                return Brushes.WhiteSmoke;
            else
            {
                //var b = new SolidColorBrush(Colors.Red);
                //b.Opacity = 0.7;
                //b.Freeze();
                //return b;
                return Brushes.Red;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class DownloadPercentToTextConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int downloadPercent = (int)values[0];
            int errorCode = (int)values[1];

            return errorCode == 0 ? new Run(downloadPercent + "%") : new Run(errorCode.ToString()) { Foreground = Brushes.White };
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class NotNullToVisibilityConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value != null ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class TabToCanCloseTabConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is ViewModelChat && !((ViewModelChat)value).IsPinned)
                return true;
            else
                return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class WindowPositionShakeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Double val = (double)value;
            if (Boolean.Parse(parameter.ToString()) == true)
                val = val + 10;
            else
                val = val - 10;

            return val;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class StringToUriConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return null;
            else if (String.IsNullOrEmpty(value.ToString()))
                return null;

            return new Uri(value.ToString(), UriKind.Absolute);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((Uri)value).AbsoluteUri;
        }
    }
    public class IsNullConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value == null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class StringNullOrEmptyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string)
                return String.IsNullOrEmpty((string)value);
            else
                return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


    /// <summary>
    /// Returns Visible when number is above 0, returns Collapsed if null or 0
    /// </summary>
    public class NumberToVisibilityConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || (int)value == 0)
                return Visibility.Collapsed;
            else
                return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class InverseNumberToVisibilityConverter : IValueConverter
    {
        NumberToVisibilityConverter _converter = new NumberToVisibilityConverter();

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var result = _converter.Convert(value, targetType, parameter, culture) as Visibility?;
            return result == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    //Adjusts the group header width by subracting our left margins.
    public class GroupHeaderExpanderWidthConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double width = (double)value - 30;
            if (width < 0)
                width = 0;

            return width;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// Returns the strikethrough text decoration for blocked group headers
    /// </summary>
    public class ChatGroupToTextDecorationConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is JiveChatGroupModel)
            {
                if (((JiveChatGroupModel)value).IsBlocked)
                    return TextDecorations.Strikethrough;
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    // Converter for disabling ComboboxItem
    public class ComboboxDisableConverter : DependencyObject, IValueConverter
    {

        public JiveChatGroupModel CurrentChatGroup
        {
            get { return (JiveChatGroupModel)GetValue(CurrentChatGroupProperty); }
            set { SetValue(CurrentChatGroupProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentChatGroup.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentChatGroupProperty =
            DependencyProperty.Register("CurrentChatGroup", typeof(JiveChatGroupModel), typeof(ComboboxDisableConverter), new PropertyMetadata(null));




        public IContact CurrentUser
        {
            get { return (IContact)GetValue(CurrentUserProperty); }
            set { SetValue(CurrentUserProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentUser.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentUserProperty =
            DependencyProperty.Register("CurrentUser", typeof(IContact), typeof(ComboboxDisableConverter), new PropertyMetadata(null));




        public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return value;
            if (value is GroupPrivilege)
            {
                GroupPrivilege privilege = (GroupPrivilege)value;
                GroupPrivilege currentUserPrivilege = CurrentChatGroup.GroupMembers.FirstOrDefault(x => x.Key == CurrentUser.UserName).Value;
                switch (currentUserPrivilege)
                {
                    case GroupPrivilege.Owner:
                        return false;
                    case GroupPrivilege.Moderator:
                        return true;
                    default:
                        return true;
                }
            }
            return true;
        }

        public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class TabIsPinnedToMenuHeaderConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((bool)value) == true ? "Unpin tab" : "Pin tab";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// Returns the bitmapimage for an IEmoticonModel
    /// </summary>
    public class CustomEmoticonImagePathConverter : IValueConverter
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                IEmoticon model = value as IEmoticon;
                if (model == null)
                    return null;
                if (model.Type == EmoticonType.CustomEmoticon)
                {
                    return StaticMethods.BitmapFromUri(new Uri(model.EmoticonPath, UriKind.RelativeOrAbsolute));
                }
                else
                {
                    Uri u = new Uri(string.Format("pack://application:,,,/JiveMessenger;component/{0}", model.EmoticonPath));
                    var bitmap = StaticMethods.BitmapFromUri(u);

                    return bitmap;
                }
            }
            catch (Exception e)
            {
                Logger.ErrorException("Error converting custom emoticon image path", e);
            }

            return null;
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

    }


    public class InverseBooleanToVisibilityConverter : IValueConverter
    {
        private BooleanToVisibilityConverter _converter = new BooleanToVisibilityConverter();

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var result = _converter.Convert(value, targetType, parameter, culture) as Visibility?;
            return result == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var result = _converter.ConvertBack(value, targetType, parameter, culture) as bool?;
            return result == true ? false : true;
        }
    }
    /// <summary>
    /// Returns black brush if true, else red brush.
    /// </summary>
    public class BoolToValidEmoticonBrush : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool isValid = (bool)value;
            return isValid ? Brushes.Black : Brushes.Red;
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


    /// <summary>
    /// Converts byte array to avatar bitmap image, returns default avatar image if input is null.
    /// </summary>
    public class ByteArrayToAvatarImageSourceConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            byte[] array = value as byte[];
            if (array != null)
            {
                return StaticMethods.ByteArrayToBitmap(array);// array.ToBitmapImage();
            }

            return new BitmapImage(new Uri("/JiveMessenger;component/Resources/Images/avatar_empty.png", UriKind.Relative));
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// Returns the description text for an enum.
    /// </summary>
    public class NotificationTypeToTextConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            NotificationType t = (NotificationType)value;
            return StaticMethods.GetEnumDescription(t);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// Returns the formatted notification message for an INotification.
    /// </summary>
    public class NotificationToTextConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var notification = (NotificationBase)value;
            string returnText = string.Empty;
            switch (notification.NotificationType)
            {
                case NotificationType.FriendInvite:
                    {
                        var n = (FriendInviteNotification)notification;
                        returnText = string.Format("{0} has sent a friend request {1}", n.SenderUsername, String.IsNullOrEmpty(n.NotificationText) ? string.Empty : ": " + n.NotificationText);
                        break;
                    }
                case NotificationType.GroupInvite:
                    {
                        var n = (GroupInviteNotification)notification;
                        returnText = string.Format("{0} invites you to the group {1} {2}", n.SenderUsername, n.Group.Name, String.IsNullOrEmpty(n.NotificationText) ? string.Empty : ": " + n.NotificationText);
                        break;
                    }
                case NotificationType.ServerMessage:
                    returnText = string.Format("Info: {0}", notification.NotificationText);
                    break;
                case NotificationType.UpdateAvailable:
                    {
                        var n = (UpdateAvailableNotification)notification;

                        returnText = n.NotificationText;
                        break;
                    }
            }
            return returnText;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// Returns a one line string summary for a List of notifications.
    /// </summary>
    public class NotificationListToTextConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var notifications = value as ICollection<NotificationBase>;
            if (notifications != null)
            {
                string returnVal = string.Empty;
               // List<List<INotification>> valuesByType = notifications.GroupBy(x => x.NotificationType).Select(x => x.Select(v => v).ToList()).ToList();
                var valuesByType = notifications.ToLookup(x => x.NotificationType);
                foreach (var subGroup in valuesByType)
                {
                    returnVal += string.Format("{0} new {1}, ", subGroup.Count(), StaticMethods.GetEnumDescription(subGroup.Key));
                }
                returnVal = returnVal.TrimEnd().TrimEnd(',');
                return returnVal;
            }
            else
                return string.Empty;
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
    }
    /// <summary>
    /// Returns comma separated list of shortcuts for a string array with emoticon shortcuts or a shortcut string
    /// </summary>
    public class EmoticonShortCutToTextConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string)
                return (string)value;
            else if (value is string[])
            {
                string[] shortCutArray = value as string[];
                return shortCutArray.Aggregate((A, B) => A + " " + B);
            }
            else
                return string.Empty;
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
    }

    public class ClientStatusToBorderBrushConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ClientStatus status = (ClientStatus)value;
            switch (status)
            {
                case ClientStatus.Afk:
                    return (LinearGradientBrush)App.Current.Resources["ButtonGradientBrushAFK"];
                case ClientStatus.Available:
                    return (LinearGradientBrush)App.Current.Resources["ButtonGradientBrushOnline"];
                case ClientStatus.Busy:
                    return (LinearGradientBrush)App.Current.Resources["ButtonGradientBrushBusy"];
                case ClientStatus.Offline:
                default:
                    return (LinearGradientBrush)App.Current.Resources["ButtonGradientBrushOffline"];
            }

        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ClientStatusToStatusTextConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ClientStatus status = (ClientStatus)value;
            switch (status)
            {
                case ClientStatus.Afk:
                    return "Away";
                case ClientStatus.Available:
                    return "Available";
                case ClientStatus.Busy:
                    return "Busy";
                case ClientStatus.Offline:
                default:
                    return "Offline";
            }
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


    public class ValidationAndStatusTextConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string validationError = values.Length > 0 ? (values[0] != null ? values[0].ToString() : "") : "";
            string serverStatusText = values.Length > 1 ? (values[1] != null ? values[1].ToString() : "") : "";

            if (!string.IsNullOrEmpty(validationError) && validationError != DependencyProperty.UnsetValue.ToString())
                return validationError;
            else
                return serverStatusText;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class ContactNameConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string nickname = values.Length > 0 ? (values[0] != null ? values[0].ToString() : "") : "";
            string username = values.Length > 1 ? (values[1] != null ? values[1].ToString() : "") : "";

            if (!string.IsNullOrEmpty((string)nickname))
                return (string)nickname;
            else
                return username;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ContactGroupStatusConverter : DependencyObject, IValueConverter
    {


        public JiveClientStatusGroupModel OnlineGroup
        {
            get { return (JiveClientStatusGroupModel)GetValue(OnlineGroupProperty); }
            set { SetValue(OnlineGroupProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OnlineGroup.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OnlineGroupProperty =
            DependencyProperty.Register("OnlineGroup", typeof(JiveClientStatusGroupModel), typeof(ContactGroupStatusConverter), new PropertyMetadata(null));



        public JiveClientStatusGroupModel OfflineGroup
        {
            get { return (JiveClientStatusGroupModel)GetValue(OfflineGroupProperty); }
            set { SetValue(OfflineGroupProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OfflineGroup.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OfflineGroupProperty =
            DependencyProperty.Register("OfflineGroup", typeof(JiveClientStatusGroupModel), typeof(ContactGroupStatusConverter), new PropertyMetadata(null));



        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ClientStatus status = (ClientStatus)value;
            return Convert(status, OnlineGroup, OfflineGroup);
        }
        private static JiveClientStatusGroupModel Convert(ClientStatus status, JiveClientStatusGroupModel onlineGroup, JiveClientStatusGroupModel offlineGroup)
        {
            if (status == ClientStatus.Available || status == ClientStatus.Afk || status == ClientStatus.Busy)
                return onlineGroup;
            else
                return offlineGroup;
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ChatGroupToGroupMemberCountConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {

            if (value is IChatGroup)
            {
                IChatGroup model = (IChatGroup)value;
                switch (model.Type)
                {
                    case GroupType.JiveChatGroup:
                        JiveChatGroupModel group = (JiveChatGroupModel)value;
                        int count = group.GroupMembers.Count - 1;
                        return count > 0 ? "/" + count : string.Empty;
                    default:
                        return string.Empty;
                }

            }
            else
                return string.Empty;
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ContactChatGroupConverter : DependencyObject, IValueConverter
    {
        //    private readonly JiveFriendsGroupModel FriendsGroup = new JiveFriendsGroupModel();// new JiveChatGroupModel(Int32.MaxValue.ToString(), "Friends");



        public JiveFriendsGroupModel FriendsGroup
        {
            get { return (JiveFriendsGroupModel)GetValue(FriendsGroupProperty); }
            set { SetValue(FriendsGroupProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FriendsGroup.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FriendsGroupProperty =
            DependencyProperty.Register("FriendsGroup", typeof(JiveFriendsGroupModel), typeof(ContactChatGroupConverter), new PropertyMetadata(null));



        public JiveFriendsGroupModel OfflineFriendsGroup
        {
            get { return (JiveFriendsGroupModel)GetValue(OfflineFriendsGroupProperty); }
            set { SetValue(OfflineFriendsGroupProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OfflineFriendsGroup.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OfflineFriendsGroupProperty =
            DependencyProperty.Register("OfflineFriendsGroup", typeof(JiveFriendsGroupModel), typeof(ContactChatGroupConverter), new PropertyMetadata(null));

        public ObservableCollection<IContact> ContactModels
        {
            get { return (ObservableCollection<IContact>)GetValue(ContactModelsProperty); }
            set { SetValue(ContactModelsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentClient.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ContactModelsProperty =
            DependencyProperty.Register("ContactModels", typeof(ObservableCollection<IContact>), typeof(ContactChatGroupConverter), new PropertyMetadata(null));

        public IContact CurrentClient
        {
            get { return (IContact)GetValue(CurrentClientProperty); }
            set { SetValue(CurrentClientProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentClient.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentClientProperty =
            DependencyProperty.Register("CurrentClient", typeof(IContact), typeof(ContactChatGroupConverter), new PropertyMetadata(null));

        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            IContact model = (IContact)value;
            return Convert(model, ContactModels, FriendsGroup, OfflineFriendsGroup, CurrentClient);
        }
        private static ObservableCollection<IChatGroup> Convert(IContact model, ObservableCollection<IContact> contactModels, JiveFriendsGroupModel friendsGroup, JiveFriendsGroupModel offlineFriendsGroup, IContact currentClient)
        {
            friendsGroup.MemberCount = contactModels.Count;
            var groups = model.ChatGroups;
            if (groups == null || groups.Count == 0 || model.ClientStatus == ClientStatus.Offline)
            {
                if (model.IsFriend)
                    return new ObservableCollection<IChatGroup> { offlineFriendsGroup };
                else
                    return new ObservableCollection<IChatGroup>();
            }
            else
            {
                var groupList = groups.Where(x => currentClient.ChatGroups.Any(y => y.ID == x.ID)).ToList();
                if (model.IsFriend)
                    groupList.Add(friendsGroup);

                return new ObservableCollection<IChatGroup>(groupList.OrderBy(x => x.Name));
            }
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    //public class ChatGroupToGroupNameConverter : IValueConverter
    //{
    //    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    //    {

    //        if (value is IChatGroup)
    //            return ((IChatGroup)value).Name;
    //        else
    //            return value;

    //    }
    //    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    //    {
    //        throw new NotImplementedException();
    //    }
    //}
    public class ChatGroupToIgnoreVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is IChatGroup)
            {
                IChatGroup model = (IChatGroup)value;
                switch (model.Type)
                {
                    case GroupType.JiveChatGroup:
                        return ((JiveChatGroupModel)value).IsBlocked ? Visibility.Visible : Visibility.Collapsed;
                    default:
                        return Visibility.Collapsed;
                }
            }
            else
                return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class ChatGroupToBlockGroupHeaderText : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            IChatGroup model = (IChatGroup)value;
            switch (model.Type)
            {
                case GroupType.JiveChatGroup:
                    return ((JiveChatGroupModel)value).IsBlocked ? "Unblock Group" : "Block Group";
                default:
                    return "Block group";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class ChatGroupToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            GroupItem gi = value as GroupItem;
            if (gi != null)
            {
                CollectionViewGroup cv = gi.DataContext as CollectionViewGroup;
                if (cv != null)
                {
                    if (cv.Name != null && cv.Name is IChatGroup && ((IChatGroup)cv.Name).Type != GroupType.JiveFriendsGroup)//.Name != "Friends")
                    {
                        var parent = VisualTreeHelper.GetParent(gi);
                        if (parent != null)
                        {
                            ItemsPresenter presenter = (ItemsPresenter)VisualTreeHelper.GetParent(parent);
                            if (presenter != null)
                            {
                                GroupItem g = presenter.TemplatedParent as GroupItem;
                                if (g != null)
                                {
                                    CollectionViewGroup cvg = g.DataContext as CollectionViewGroup;
                                    if (cvg != null && ((JiveClientStatusGroupModel)cvg.Name).Status == JiveStatusGroupStatus.Offline)//(string)cvg.Name == "Offline")
                                    {
                                        return Visibility.Collapsed;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
 
    public class ContactModelToIgnoreContactHeaderText : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool isIgnored = (bool)value;
            return isIgnored ? "Unignore contact" : "Ignore contact";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class DeviceTypeToContactImageConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DeviceType type = (DeviceType)value;
            if (type == DeviceType.PC)
                return new Uri("/JiveMessenger;component/Resources/Images/50x50-inverted-outline.png", UriKind.Relative);
            else if (type == DeviceType.Android || type == DeviceType.WindowsPhone)
                return new Uri("/JiveMessenger;component/Resources/Images/mobile_icon_3.png", UriKind.Relative);
            else
                return new Uri("/JiveMessenger;component/Resources/Images/50x50-inverted-outline.png", UriKind.Relative);

        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    sealed class ClientStatusToContactImageConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ClientStatus status = (ClientStatus)value;
            switch (status)
            {
                case ClientStatus.Afk:
                    return new Uri("/JiveMessenger;component/Resources/Images/contact_afk_50x50.png", UriKind.Relative);
                case ClientStatus.Available:
                    return new Uri("/JiveMessenger;component/Resources/Images/contact_available_50x50.png", UriKind.Relative);
                case ClientStatus.Busy:
                    return new Uri("/JiveMessenger;component/Resources/Images/contact_busy_50x50.png", UriKind.Relative);
                case ClientStatus.Offline:
                default:
                    return new Uri("/JiveMessenger;component/Resources/Images/contact_offline_50x50.png", UriKind.Relative);
            }
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class BoolToGridSplitterImageSourceConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {

            bool isOpen = (bool)value;
            if (isOpen)
                return new Uri("/JiveMessenger;component/Resources/Images/arrow_left_small.png", UriKind.Relative);
            else
                return new Uri("/JiveMessenger;component/Resources/Images/arrow_right_small.png", UriKind.Relative);
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

}
